using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Extention.ENode.Rpc.Attributes;
using Extention.ENode.Rpc.DependencyResolver.Builder;
using Extention.ENode.Rpc.Proxy;
using Microsoft.Extensions.DependencyInjection;

namespace Extention.ENode.Rpc.Entry
{
    public static class ClientProxy
    {

        
        /// <summary>
        /// 默认使用应用程序下包含interfaces的库作为扫描基础
        /// </summary>
        /// <param name="consulUrl"></param>
        /// <returns></returns>
        public static void GenerateAll()
        {
            ProxyAll();
        }
        private static ServiceCollection serviceCollection = new ServiceCollection();
        private static ServiceProvider Builder()
        {
            return serviceCollection.BuildServiceProvider();
        }
        /// <summary>
        /// 初始化所有Client端代理注入
        /// </summary>
        private static void ProxyAll()
        {
            IServiceProxyGenerater serviceProxyGenerate = null;
            IServiceProxyFactory serviceProxyFactory = null;
            if (ECommon.Components.ObjectContainer.Current == null)
            {
                var serviceProvider = Builder();
                serviceProxyGenerate = serviceProvider.GetRequiredService<IServiceProxyGenerater>();
                serviceProxyFactory = serviceProvider.GetRequiredService<IServiceProxyFactory>();

            }
            else
            {
                serviceProxyGenerate = ECommon.Components.ObjectContainer.Resolve<IServiceProxyGenerater>();
                serviceProxyFactory = ECommon.Components.ObjectContainer.Resolve<IServiceProxyFactory>();
            }


            var path = AppDomain.CurrentDomain.BaseDirectory;
            var files = new DirectoryInfo(path).GetFiles();
            var types = (from file in files
                         where file.Extension.ToLower().Contains(".dll")
                         from type in Assembly.LoadFrom(file.ToString()).GetExportedTypes()
                         where type.IsInterface && type.GetCustomAttributes(typeof(ServiceBundleAttribute), true).Length > 0
                         select type).ToList();

            var objs = serviceProxyGenerate.GenerateProxys(types, new List<string> { "EStart.Common" })
                .Select(proxy => serviceProxyFactory.CreateProxy(proxy))
                .ToList();

            foreach (var item in objs)
            {
                var imItem = item.GetType();
                var iService = types.Where(n => imItem.GetInterfaces().Contains(n)).FirstOrDefault();
                if (iService != null)
                {
                    object ins;
                    var imp = ECommon.Components.ObjectContainer.TryResolve(iService,out ins);
                    if (ins == null)
                    {
                        ECommon.Components.ObjectContainer.RegisterType(iService, imItem);
                    }
                }
            }

        }
      
    }
}